package com.asiainfo.commons.util;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ai.appframe2.bo.dialect.DialectFactory;
import com.ai.appframe2.common.DataContainerInterface;
import com.ai.appframe2.common.ObjectType;
import com.ai.appframe2.common.ServiceManager;
import com.ai.appframe2.complex.tab.split.SplitTableFactory;
import com.ai.appframe2.complex.tab.split.TableVars;
import com.ai.secframe.common.util.TablesplitUtil;
import com.asiainfo.ssm.execute.bo.BOExecOrderBean;

public class SplitTableUtil {

	private static transient Log log = LogFactory.getLog(SplitTableUtil.class);
	
	public static String getUnionSqlByMonth(Connection conn,ObjectType oType,Timestamp startDate,Timestamp endDate,String columnName, String condition)throws Exception{
		
		String sql = DialectFactory.getDialect().getSelectSQL(conn,oType,null, null, -1, -1, false,false, null);
		List monthList = getEndDateAndStartDate(startDate,endDate);
		String[] unionSqls = new String[monthList.size()];
		String[] tableNames = com.ai.appframe2.util.StringUtils.getParamFromString(sql, "{", "}");
		for (int i = 0; i < monthList.size(); ++i) {
			TableVars objTableVars = new TableVars();
			for (int j = 0; j < tableNames.length; ++j) {
				objTableVars.add(tableNames[j], columnName,(String) monthList.get(i));
			}
			StringBuffer strSql = new StringBuffer();
			strSql.append(sql);
			if (StringUtils.isNotBlank(condition)) {
				strSql.append(condition);
			}
			unionSqls[i] = SplitTableFactory.createQuerySQL(strSql.toString(),objTableVars);
		}

		StringBuffer buffer = new StringBuffer();
		buffer.append(StringUtils.join(unionSqls, " union all "));

		return buffer.toString();
	}
	
	public static int getUnionQueryCount(Connection conn,ObjectType oType,Timestamp startDate,Timestamp endDate,String columnName, String condition)throws Exception{
		int result = 0;
		String sql = getUnionSqlByMonth(conn, oType, startDate, endDate, columnName, condition);
		String countSql = " select count(*) from ("+sql+")";
		PreparedStatement ptmt = conn.prepareStatement(countSql);
		ResultSet rs = ptmt.executeQuery();

		if (rs.next()) {
			result = rs.getInt(1);
		}
		return result;
	}
	
	public static DataContainerInterface[] getUnionQuery(Class paramClass,Connection conn,ObjectType oType,Timestamp startDate,Timestamp endDate,String columnName, String condition,String unionCond,int start,int end) throws Exception{
		String sql = getUnionSqlByMonth(conn, oType, startDate, endDate, columnName, condition);
		String realSql = TablesplitUtil.createRowIndexSql(sql, unionCond);
		if(start>-1&&end>-1){
			realSql += " where rowindex >="+start+" and rowindex <="+end;
		}
		if(log.isDebugEnabled()){
			log.debug(realSql);
		}
		PreparedStatement ptmt = conn.prepareStatement(realSql);
		return ServiceManager.getDataStore().crateDtaContainerFromResultSet(BOExecOrderBean.class, BOExecOrderBean.getObjectTypeStatic(), ptmt.executeQuery(), null, false);
	}
	
	private static List getEndDateAndStartDate(Date sdate, Date edate)
			throws Exception {
		Calendar cal = Calendar.getInstance();
		List rtn = new ArrayList();
		DateFormat dateformat = new SimpleDateFormat("yyyyMM");
		rtn.add(dateformat.format(sdate));

		long months = monthsBetween(sdate, edate);
		for (int i = 1; i <= months; ++i) {
			cal.setTime(sdate);
			cal.add(2, i);
			rtn.add(dateformat.format(cal.getTime()));
		}
		return rtn;
	}
	private static int monthsBetween(Date sdate, Date edate) {
		Calendar c = Calendar.getInstance();
		c.setTime(sdate);
		int beginYear = c.get(1);
		int beginMonth = c.get(2);

		c.setTime(edate);
		int endYear = c.get(1);
		int endMonth = c.get(2);

		int difMonth = (endYear - beginYear) * 12 + endMonth - beginMonth;

		return difMonth;
	}
}
